﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using GameSchoolApplication.Models;
using GameSchoolApplication.Repositories;
using GameSchoolApplication.Classes;
using GameSchoolApplication.Models.ViewModels;
using System.IO;

namespace GameSchoolApplication.Controllers
{
    public class AssignmentController : Controller
    {
        //
        // GET: /Assignment/
        /// <summary>
        /// Gets the view for a particular assignment and returns it to the user.
        /// Precondition: The user clicks the assignment link
        /// Postcondition: The user has received the assignment view
        /// Author: Krilli
        /// Date: 5.5 10:30
        /// <param name="ID">The ID of the desired assignment</param>
        /// <returns>The view  for the assignment</returns>
        /// </summary>
        
        public ActionResult getAssignment(int ID)
        {
            //Initialize the repository
            AssignmentRepository rep = new AssignmentRepository();
            Assignment ass = rep.getAssignmentByID(ID);
            //This probably needs to be edited when the views are done. 
            return View("AssDisplay", ass);
        }

        /// <summary>
        /// skilar lista yfir assingments í level sem Json
        /// precondition:levelID needs to exist in the database
        /// </summary>
        /// <param name="levelID">levelID for the desired level.</param>
        /// <returns></returns>
        public ActionResult getLevelAssignmentList(int levelID)
        {
            AssignmentRepository rep = new AssignmentRepository();
            var assList = (from ass in rep.getAssignmentsOfLevel(levelID)
                           select new { assID = ass.assignmentID, assName = ass.name, pointValue = ass.reward });

            return Json(assList, JsonRequestBehavior.AllowGet);
        }

        /// <summary>
        /// Returns the edit view for a particular assignment
        /// Precondition: The user clicks the edit assignment for a particular assignment
        /// Postcondition: The user has received the edit view for that assignment
        /// Author: Krilli
        /// Date:  5.5 10:40
        /// <param name="ID">The ID of the desired assignment</param>
        /// <returns>The edit view for the assignment</returns>
        /// </summary>
        public ActionResult editAssignment(int ID)
        {
            //Initialize the repository
            AssignmentRepository rep = new AssignmentRepository();
            Assignment ass = rep.getAssignmentByID(ID);
            //This probably needs to be edited when the views are done
            return View(ass);
        }


        /// <summary>
        /// Submits the edited assignment information to the repository. 
        /// Precondition: The user has entered edit information and submitted it 
        /// Postcondition: The information has been submitted to the repository
        /// Author: Krilli
        /// Date:  5.5
        /// <param name="assingmentModel">The model of the assignment in question</param>
        /// </summary>
        public ActionResult editAssignmentSubmit(Assignment assignmentModel)
        {
            //This is a bit tricky. Going to do it when I'm not hungover as shit and capable of communicating with people. 
            return View();
        }

        /// <summary>
        /// Returns the grading view for a particular assignment
        /// Precondition: The user has clicked the grade button for the assignment
        /// Postcondition: The user has received the grading view for that particular assignment
        /// Author: Krilli
        /// Date:  5.5
        /// </summary>
        /// <param name="assignmentID">The ID of the desired assignment</param>
        /// <returns>The grading view for that assignment</returns>
        public ActionResult gradeAssignment(int submissionID)
        {
            //Initialize the repository, get the desired assignment
            SubmissionRepository rep = new SubmissionRepository();
            Submission sub = rep.getSubmissionByID(submissionID);
            return View(sub);
        }

        /// <summary>
        /// Submits the updated grade to the database. Note: Only submits grade changes. 
        /// Precondition: The teacher has entered grading information to the database
        /// Postcondition: The grade has been submitted
        /// Author: Krilli 
        /// Date: 8.5
        /// </summary>
        /// 
        [HttpPost]
        public ActionResult gradeAssignment(Submission model)
        {
            SubmissionRepository rep = new SubmissionRepository();
            Submission old = rep.getSubmissionByID(model.submissionID);
            old.grade = model.grade;
            bool success = rep.editSubmission(old);
            if (success)
            {
                return View("win");
            }
            else
            {
                return View("fail");
            }
        }

        /// <summary>
        /// Uploads a assignment submission to the database. 
        /// Precondition: the user has entered the desired file into the form.
        /// Postcondition: A submission has been created, which is linked to a usersubmission, which has a submission file. 
        ///                 This has all been submitted to the database. 
        /// Author: Krilli
        /// Date: 9.5
        /// </summary>
        /// <param name="model">The assignment </param>
        /// <param name="file">The file</param>
        /// <returns></returns>
        [HttpPost]
        public ActionResult uploadAss(Assignment model, HttpPostedFileBase file)
        {
            AccountRepository accountRep = new AccountRepository();
            //HttpCookie userInfo = new HttpCookie("userInfo");
            //userInfo = Request.Cookies["userInfo"];
            if (Request.Cookies["userInfo"] == null)
            {
                RedirectToAction("Index", "Home");
            }
            else
            {
                string filePath = Server.MapPath("~/App_Data/uploads");
                try
                {
                    filePath += file.FileName;
                }
                catch
                {
                    return View("fail");
                }
                //Upload the file
                Uploader(file); 
                //TODO: Fish out the filepath string
                string userName = Request.Cookies["userInfo"]["name"];
                SubmissionRepository subRep = new SubmissionRepository();
                //Create new submission and submit to the database
                Submission sub = new Submission();
                sub.assignmentID = model.assignmentID;
                sub.dateOfSubmission = DateTime.Now;
                int subID = subRep.addSubmission(sub);

                //Find the userID of the username
                AccountRepository acRep = new AccountRepository();
                UserAccount account = acRep.getAccountByName(userName);
                //Create new StudentSubmission and submit it
                StudentSubmission studentSub = new StudentSubmission();
                subRep.addStudentSubmission(subID, account.userID);

                //Create new file submission
                subRep.addFileForSubmission(subID, filePath);

                return RedirectToAction("AssDisplay", new { ID = model.assignmentID });
            }

            
            return View();
        }

        /// <summary>
        /// Uploader. Uploads the file to the specified path. 
        /// Author: Darin Dimitrov, taken from http://stackoverflow.com/questions/5193842/file-upload-asp-net-mvc3-0
        /// </summary>
        /// <param name="file"></param>
        [HttpPost]
        public void Uploader(HttpPostedFileBase file)
        {
            // Verify that the user selected a file
            if (file != null && file.ContentLength > 0)
            {
                // extract only the fielname
                var fileName = Path.GetFileName(file.FileName);
                // store the file inside ~/App_Data/uploads folder
                var path = Path.Combine(Server.MapPath("~/App_Data/uploads"), fileName);
                file.SaveAs(path);
            }
        }

        
        /// <summary>
        /// Displays the file submission form for a assignment. 
        /// Precondition:
        /// Postcondition: The view has been returned to the user. 
        /// </summary>
        /// <param name="ID"></param>
        /// <returns></returns>
        public ActionResult AssDisplay(int ID)
        {
            AssignmentRepository assRep = new AssignmentRepository();
            Assignment ass = assRep.getAssignmentByID(ID); 
            return View(ass); 
        }

        /// <summary>
        /// Returns the submissions view for a particular assignment
        /// Precondition: The user has clicked the submissions button for a particular assignment
        /// Postcondition: The user has received the view. 
        /// Author: Krilli
        /// Date: 9.5
        /// </summary>
        /// <param name="assignmentID"></param>
        /// <returns></returns>
        public ActionResult AssignmentSubmissionsDisplay(int assignmentID)
        {
            SubmissionRepository subRep = new SubmissionRepository();
            AccountRepository accRep = new AccountRepository(); 
            Dictionary<string, int> dict = subRep.getSubmissionsOfAssignment(assignmentID);

            //Turn into a dictionary of user accounts and submissions. 
            Dictionary<UserAccount, Submission> list = new Dictionary<UserAccount, Submission>();
            foreach (KeyValuePair<string, int> r in dict)
            {
                list.Add(accRep.getAccountByID(r.Key), subRep.getSubmissionByID(r.Value));
            }
            return View(list); 
        }

        /// <summary>
        /// Returns the file submissions for a particular submission
        /// Precondition: The user has clicked the file submissions button for a particular submission
        /// Postcondition: The user has received the view.
        /// Author: Krilli
        /// Date: 9.5
        /// </summary>
        /// <param name="submissionID"></param>
        /// <returns></returns>

        public ActionResult FileSubmissionsDisplay(int submissionID)
        {
            SubmissionRepository subRep = new SubmissionRepository();
            IQueryable<FilesForSubmission> fileSubs = subRep.getFilesForSubmission(submissionID);
            return View(fileSubs);
        }


        /*
        public ActionResult downloadFile(int fileSubmissionID)
        {
            SubmissionRepository subRep = new SubmissionRepository();
            IQueryable<FilesForSubmission> FFS = subRep.getFilesForSubmission(fileSubmissionID);
            string returnPath = "nope";
            foreach(var s in FFS)
            {
                if (s.submissionID == fileSubmissionID)
                {
                    returnPath = s.fname;
                }
            }
            //return Redirect("http://www.example.com");
            downloadFileodel = new downloadFile();
            model.fileUrl = returnPath;
         
            return View(model); 
            
        }
         * */
    }
}
